home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / GAS_1_38.ARJ / AS.C < prev    next >
C/C++ Source or Header  |  1990-10-11  |  8KB  |  306 lines

  1. /* as.c - GAS main program.
  2.    Copyright (C) 1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  * Main program for AS; a 32-bit assembler of GNU.
  22.  * Understands command arguments.
  23.  * Has a few routines that don't fit in other modules because they
  24.  * are shared.
  25.  *
  26.  *
  27.  *            bugs
  28.  *
  29.  * : initialisers
  30.  *    Since no-one else says they will support them in future: I
  31.  * don't support them now.
  32.  *
  33.  */
  34.  
  35. #ifdef _POSIX_SOURCE
  36. #include <sys/types.h>    /* For pid_t in signal.h */
  37. #endif
  38. #include <signal.h>
  39.  
  40. #define COMMON
  41. #include "as.h"
  42. #include "struc-symbol.h"
  43. #include "write.h"
  44.         /* Warning!  This may have some slightly strange side effects
  45.            if you try to compile two or more assemblers in the same
  46.            directory!
  47.          */
  48.  
  49. #ifndef SIGTY
  50. #define SIGTY int
  51. #endif
  52.  
  53. SIGTY got_sig();
  54.  
  55. #ifdef DONTDEF
  56. static char * gdb_symbol_file_name;
  57. long int gdb_begin();
  58. #endif
  59.  
  60. char *myname;        /* argv[0] */
  61. extern char version_string[];
  62.  
  63. main(argc,argv)
  64. int    argc;
  65. char    **argv;
  66. {
  67.     int    work_argc;    /* variable copy of argc */
  68.     char    **work_argv;    /* variable copy of argv */
  69.     char    *arg;        /* an arg to program */
  70.     char    a;        /* an arg flag (after -) */
  71.     static const int sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
  72.  
  73.     extern int bad_error;    /* Did we hit a bad error ? */
  74.  
  75.     char    *stralloc();    /* Make a (safe) copy of a string. */
  76.     void    symbol_begin();
  77.     void    read_begin();
  78.     void    write_object_file();
  79.  
  80.     for(a=0;sig[a]!=0;a++)
  81.         if(signal(sig[a], SIG_IGN) != SIG_IGN)
  82.             signal(sig[a], got_sig);
  83.  
  84.     myname=argv[0];
  85.     bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */
  86.     out_file_name    = "a.out";    /* default .o file */
  87.     symbol_begin();        /* symbols.c */
  88.     subsegs_begin();        /* subsegs.c */
  89.     read_begin();            /* read.c */
  90.     md_begin();            /* MACHINE.c */
  91.     input_scrub_begin();        /* input_scrub.c */
  92. #ifdef DONTDEF
  93.     gdb_symbol_file_name = 0;
  94. #endif
  95.     /*
  96.      * Parse arguments, but we are only interested in flags.
  97.      * When we find a flag, we process it then make it's argv[] NULL.
  98.      * This helps any future argv[] scanners avoid what we processed.
  99.      * Since it is easy to do here we interpret the special arg "-"
  100.      * to mean "use stdin" and we set that argv[] pointing to "".
  101.      * After we have munged argv[], the only things left are source file
  102.      * name(s) and ""(s) denoting stdin. These file names are used
  103.      * (perhaps more than once) later.
  104.      */
  105.     work_argc = argc-1;        /* don't count argv[0] */
  106.     work_argv = argv+1;        /* skip argv[0] */
  107.     for (;work_argc--;work_argv++) {
  108.         arg = * work_argv;    /* work_argv points to this argument */
  109.  
  110.         if (*arg!='-')        /* Filename. We need it later. */
  111.             continue;    /* Keep scanning args looking for flags. */
  112.         if (arg[1] == '-' && arg[2] == 0) {
  113.             /* "--" as an argument means read STDIN */
  114.             /* on this scan, we don't want to think about filenames */
  115.             * work_argv = "";    /* Code that means 'use stdin'. */
  116.             continue;
  117.         }
  118.                 /* This better be a switch. */
  119.         arg ++;        /* -> letter. */
  120.  
  121.         while (a = * arg)  {/* scan all the 1-char flags */
  122.             arg ++;    /* arg -> after letter. */
  123.             a &= 0x7F;    /* ascii only please */
  124.             if (flagseen[a])
  125.                 as_warn("%s: Flag option -%c has already been seen!",myname,a);
  126.             flagseen[a] = TRUE;
  127.             switch (a) {
  128.             case 'f':
  129.                 break;    /* -f means fast - no need for "app" preprocessor. */
  130.  
  131.             case 'D':
  132.                 /* DEBUG is implemented: it debugs different */
  133.                 /* things to other people's assemblers. */
  134.                 break;
  135.  
  136. #ifdef DONTDEF
  137.             case 'G':    /* GNU AS switch: include gdbsyms. */
  138.                 if (*arg)    /* Rest of argument is file-name. */
  139.                     gdb_symbol_file_name = stralloc (arg);
  140.                 else if (work_argc) {    /* Next argument is file-name. */
  141.                     work_argc --;
  142.                     * work_argv = NULL; /* Not a source file-name. */
  143.                     gdb_symbol_file_name = * ++ work_argv;
  144.                 } else
  145.                     as_warn( "%s: I expected a filename after -G",myname);
  146.                 arg = "";    /* Finished with this arg. */
  147.                 break;
  148. #endif
  149.  
  150. #ifndef WORKING_DOT_WORD
  151.             case 'k':
  152.                 break;
  153. #endif
  154.  
  155.             case 'L': /* -L means keep L* symbols */
  156.                 break;
  157.  
  158.             case 'o':
  159.                 if (*arg)    /* Rest of argument is object file-name. */
  160.                     out_file_name = stralloc (arg);
  161.                 else if (work_argc) {    /* Want next arg for a file-name. */
  162.                     * work_argv = NULL; /* This is not a file-name. */
  163.                     work_argc--;
  164.                     out_file_name = * ++ work_argv;
  165.                 } else
  166.                     as_warn("%s: I expected a filename after -o. \"%s\" assumed.",myname,out_file_name);
  167.                 arg = "";    /* Finished with this arg. */
  168.                 break;
  169.  
  170.             case 'R':
  171.                 /* -R means put data into text segment */
  172.                 break;
  173.  
  174.             case 'v':
  175. #ifdef    VMS
  176.                 {
  177.                 extern char *compiler_version_string;
  178.                 compiler_version_string = arg;
  179.                 }
  180. #else /* not VMS */
  181.                 fprintf(stderr,version_string);
  182.                 if(*arg && strcmp(arg,"ersion"))
  183.                     as_warn("Unknown -v option ignored");
  184. #endif
  185.                 while(*arg) arg++;    /* Skip the rest */
  186.                 break;
  187.  
  188.             case 'W':
  189.                 /* -W means don't warn about things */
  190.                 break;
  191.  
  192.             default:
  193.                 --arg;
  194.                 if(md_parse_option(&arg,&work_argc,&work_argv)==0)
  195.                     as_warn("%s: I don't understand '%c' flag!",myname,a);
  196.                 if(arg && *arg)
  197.                     arg++;
  198.                 break;
  199.             }
  200.         }
  201.         /*
  202.          * We have just processed a "-..." arg, which was not a
  203.          * file-name. Smash it so the
  204.          * things that look for filenames won't ever see it.
  205.          *
  206.          * Whatever work_argv points to, it has already been used
  207.          * as part of a flag, so DON'T re-use it as a filename.
  208.          */
  209.         *work_argv = NULL; /* NULL means 'not a file-name' */
  210.     }
  211. #ifdef DONTDEF
  212.     if (gdb_begin(gdb_symbol_file_name) == 0)
  213.         flagseen ['G'] = 0;    /* Don't do any gdbsym stuff. */
  214. #endif
  215.     /* Here with flags set up in flagseen[]. */
  216.     perform_an_assembly_pass(argc,argv); /* Assemble it. */
  217.     if (seen_at_least_1_file() && !bad_error)
  218.         write_object_file();/* relax() addresses then emit object file */
  219.     input_scrub_end();
  220.     md_end();            /* MACHINE.c */
  221. #ifndef    VMS
  222.     exit(bad_error);            /* WIN */
  223. #else    /* VMS */
  224.     exit(!bad_error);            /* WIN */
  225. #endif    /* VMS */
  226. }
  227.  
  228.  
  229. /*            perform_an_assembly_pass()
  230.  *
  231.  * Here to attempt 1 pass over each input file.
  232.  * We scan argv[*] looking for filenames or exactly "" which is
  233.  * shorthand for stdin. Any argv that is NULL is not a file-name.
  234.  * We set need_pass_2 TRUE if, after this, we still have unresolved
  235.  * expressions of the form (unknown value)+-(unknown value).
  236.  *
  237.  * Note the un*x semantics: there is only 1 logical input file, but it
  238.  * may be a catenation of many 'physical' input files.
  239.  */
  240. perform_an_assembly_pass (argc, argv)
  241. int    argc;
  242. char **    argv;
  243. {
  244.     char *    buffer;        /* Where each bufferful of lines will start. */
  245.     void    read_a_source_file();
  246.     int saw_a_file = 0;
  247.  
  248.     text_fix_root        = NULL;
  249.     data_fix_root        = NULL;
  250.     need_pass_2        = FALSE;
  251.  
  252.     argv++;            /* skip argv[0] */
  253.     argc--;            /* skip argv[0] */
  254.     while (argc--) {
  255.         if (*argv) {        /* Is it a file-name argument? */
  256.             /* argv -> "" if stdin desired, else -> filename */
  257.             if (buffer = input_scrub_new_file (*argv) ) {
  258.                 saw_a_file++;
  259.                 read_a_source_file(buffer);
  260.             }
  261.         }
  262.         argv++;            /* completed that argv */
  263.     }
  264.     if(!saw_a_file)
  265.         if(buffer = input_scrub_new_file("") )
  266.             read_a_source_file(buffer);
  267. }
  268.  
  269. /*
  270.  *            stralloc()
  271.  *
  272.  * Allocate memory for a new copy of a string. Copy the string.
  273.  * Return the address of the new string. Die if there is any error.
  274.  */
  275.  
  276. char *
  277. stralloc (str)
  278. char *    str;
  279. {
  280.     register char *    retval;
  281.     register long int    len;
  282.  
  283.     len = strlen (str) + 1;
  284.     retval = xmalloc (len);
  285.     (void)strcpy (retval, str);
  286.     return (retval);
  287. }
  288.  
  289. lose()
  290. {
  291.     as_fatal( "%s: 2nd pass not implemented - get your code from random(3)",myname );
  292. }
  293.  
  294. SIGTY
  295. got_sig(sig)
  296. int sig;
  297. {
  298.     static here_before = 0;
  299.  
  300.     as_bad("Interrupted by signal %d",sig);
  301.     if(here_before++)
  302.         exit(1);
  303. }
  304.  
  305. /* end: as.c */
  306.